﻿using Sgr.Caching.Services;

namespace Sgr.Trackers
{
    public class MessageMarkByMemory : IMessageMark
    {
        private static object lockObj = new object();

        private readonly ICacheManager _cacheManager;

        public MessageMarkByMemory(ICacheManager cacheManager)
        {
            _cacheManager = cacheManager;
        }

        /// <summary>
        /// 将消息其标记为已执行（注意此处应该是原子操作）
        /// </summary>
        /// <param name="msgId">消息标识</param>
        /// <param name="effectiveSecond">有效期，单位秒（默认7天）</param>
        /// <param name="token"></param>
        /// <returns>消息在此之前已被标记 或者 标记失败 返回False</returns>
        public async Task<bool> MarkAsProcessedAsync(string msgId, int effectiveSecond = 604800, CancellationToken token = default)
        {
            //验证令牌是否存在
            bool result = false;
            bool lockWasTaken = false;
            try
            {
                System.Threading.Monitor.Enter(lockObj, ref lockWasTaken);

                await _cacheManager.GetAsync($"MessageMark-{msgId}", () =>
                {
                    result = true;
                    return '_';
                }, _cacheManager.CreateCacheEntryOptions().SetAbsoluteExpirationRelativeToNowSecond(effectiveSecond), token);
            }
            catch
            {
                result = false;
            }
            finally
            {
                if (lockWasTaken) System.Threading.Monitor.Exit(lockObj);
            }

            return result;
        }

        /// <summary>
        /// 删除消息已执行的标记
        /// </summary>
        /// <param name="msgId"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        public async Task RemoveAsync(string msgId, CancellationToken token = default)
        {
            await _cacheManager.RemoveAsync($"MessageMark-{msgId}", token);
        }
    }
}